﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace HW
{
    public static class CryptoHelper
    {
        #region aes加解密
        public static byte[] AesEncrypt(string source, string iv = "bfby_develop_dep", string key = "bfby_develop_dep", CipherMode mode = CipherMode.CBC)
        {
            var waitEncrypt = Encoding.UTF8.GetBytes(source);
            var bIV = Encoding.UTF8.GetBytes(iv);
            var bKEY = Encoding.UTF8.GetBytes(key);
            var decrypted = AesEncrypt(waitEncrypt, bIV, bKEY, mode);
            return decrypted;
        }



        public static byte[] AesEncrypt(byte[] source, byte[] iv, byte[] key, CipherMode mode = CipherMode.CBC)
        {
            Aes _aesAlgEncrypt = Aes.Create();
            _aesAlgEncrypt.Key = key;
            _aesAlgEncrypt.IV = iv;
            _aesAlgEncrypt.Mode = mode;
            _aesAlgEncrypt.Padding = PaddingMode.PKCS7;

            ICryptoTransform encryptor = _aesAlgEncrypt.CreateEncryptor();
            byte[] resultArray = encryptor.TransformFinalBlock(source, 0, source.Length);
            return resultArray;
        }



        public static string AesDecrypt(string encryptedString, string iv = "bfby_develop_dep", string key = "bfby_develop_dep", CipherMode mode = CipherMode.CBC)
        {
            var encryptedByte = Encoding.UTF8.GetBytes(encryptedString);
            var bIV = Encoding.UTF8.GetBytes(iv);
            var bKEY = Encoding.UTF8.GetBytes(key);
            var decrypted = AesDecrypt(encryptedByte, bIV, bKEY, mode);
            return Encoding.UTF8.GetString(decrypted);
        }

        public static string AesDecrypt(byte[] encryptedByte, string iv = "bfby_develop_dep", string key = "bfby_develop_dep", CipherMode mode = CipherMode.CBC)
        {
            var bIV = Encoding.UTF8.GetBytes(iv);
            var bKEY = Encoding.UTF8.GetBytes(key);
            var decrypted = AesDecrypt(encryptedByte, bIV, bKEY, mode);
            return Encoding.UTF8.GetString(decrypted);
        }

        public static byte[] AesDecrypt(byte[] encryptedByte, byte[] iv, byte[] key, CipherMode mode)
        {
            Aes _aesAlgDecrypt = Aes.Create();
            _aesAlgDecrypt.IV = iv;
            _aesAlgDecrypt.Key = key;
            _aesAlgDecrypt.Mode = mode;
            _aesAlgDecrypt.Padding = PaddingMode.PKCS7;

            ICryptoTransform decryptor = _aesAlgDecrypt.CreateDecryptor();

            var decrypted = decryptor.TransformFinalBlock(encryptedByte, 0, encryptedByte.Length);
            return decrypted;
        }
        #endregion

        #region md5摘要

        public static byte[] MD5Bytes(byte[] source)
        {
            using (MD5 md5 = new MD5CryptoServiceProvider())
            {
                return md5.ComputeHash(source);
            }

        }

        public static string MD5String(string source)
        {
            var sb = new StringBuilder();
            byte[] md5Bytes = MD5Bytes(Encoding.UTF8.GetBytes(source));
            md5Bytes.ForEach(b => sb.Append(Convert.ToString(b, 16)));
            var ss = sb.ToString();
            return ss;
        }

        public static string MD5File(string filePath)
        {
            string result = "";
            using (MD5 md5 = new MD5CryptoServiceProvider())
            {
                var source = File.ReadAllBytes(filePath);
                byte[] md5Bytes = md5.ComputeHash(source);
                result = BitConverter.ToString(md5Bytes);
                result = result.Replace("-", "");
                result = result.ToLower();
            }
            return result;
        }

        #endregion

        #region SHA256
        /// <summary>
        /// 
        /// </summary>
        /// <param name="_byte"></param>
        /// <returns></returns>
        public static byte[] SHA256Bytes(byte[] _byte)
        {
            using(SHA256 sha = SHA256.Create())
            {
                return sha.ComputeHash(_byte);
            }
        }

        public static string SHA256string(string str)
        {
            StringBuilder s = new StringBuilder();
            byte[] _byte = SHA256Bytes(Encoding.UTF8.GetBytes(str));
            _byte.ForEach (b => s.Append(string.Format("{0:x2}", b)));
            return s.ToString();
        }

        /// <summary>
        /// 对文件进行SHA256计算。如果文件路径错误或找不到文件，则返回空字符串（""）
        /// </summary>
        /// <param name="filePath">文件的路径</param>
        /// <returns>经过SHA256计算后的字符串</returns>
        public static string SHA256File(string filePath)
        {
            StringBuilder s = new StringBuilder();
            if (File.Exists(filePath))
            {
                using (SHA256 sha=SHA256.Create())
                {
                    try
                    {
                        //打开文件
                        FileStream stream = File.Open(filePath, FileMode.Open);
                        //确保位于流的开头
                        stream.Position = 0;
                        //计算
                        var _byte=sha.ComputeHash(stream);
                        //关闭文件流
                        stream.Close();
                        //将字节数组转换为十六进制字符串
                        _byte.ForEach(b => s.Append(string.Format("{0:x2}", b)));
                        //返回结果字符串
                        return s.ToString();
                    }
                    catch (Exception)
                    {

                        throw;
                    }
                }
            }
            else
            {
                return "";
            }
        }
        #endregion

        /// <summary>
        /// 返回字符串source的MD5,他们是经过UTF8编码的字节
        /// </summary>
        /// <param name="source"></param>
        /// <returns>字节串经过UTF8编码后的字符串</returns>
        public static string MD5(this string source)
        {
            return MD5String(source);
        }

    }

}
